package com.webchat.chat.web;

import com.corundumstudio.socketio.SocketIOClient;
import com.webchat.chat.core.baseEntity.Result;
import com.webchat.chat.core.baseEntity.ResultGenerator;
import com.webchat.chat.core.dto.evenMessage.MsgInfo;
import com.webchat.chat.core.dto.loginDto.LoginSuccessReturnDTO;
import com.webchat.chat.core.dto.loginDto.LoginUserDTO;
import com.webchat.chat.core.enums.MsgType;
import com.webchat.chat.core.shiro.ShiroUser;
import com.webchat.chat.core.shiro.UserToken;
import com.webchat.chat.core.tools.ChatConstant;
import com.webchat.chat.core.tools.ClientUtil;
import com.webchat.chat.core.tools.ShiroUtil;
import com.webchat.chat.core.tools.SocketConstant;
import com.webchat.chat.service.SocketClientService;
import com.webchat.chat.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * Created by Owner on 2018/6/29.
 */
@RestController
@RequestMapping(ChatConstant.CONTROLLER_ROOT_PATH + "/loginManager")
public class LoginController extends BaseController {

    @Resource
    private SocketClientService socketClientService;
    @Resource
    private UserService userService;


    @PostMapping("/login")
    public Result login(LoginUserDTO user, HttpServletRequest req) {
        String userName = user.getUserName();
        String pwdLogin = user.getPwdLogin();

        if (StringUtils.isBlank(userName) || StringUtils.isBlank(pwdLogin)) {
            return ResultGenerator.genFailResult("用户名或密码不能为空");
        }

        String ip = ClientUtil.getRemoteAddr(req);// ip
        String userAgent = ClientUtil.getBrowser(req);// 浏览器
        String sid = ClientUtil.getSessionId(req);
        String domain = ClientUtil.getDomain(req);
        UserToken token = new UserToken(userName, pwdLogin, false, userAgent, ip, sid, domain);

        Subject subject = SecurityUtils.getSubject();

        try {
            subject.login(token);
        } catch (Exception e) {
            return ResultGenerator.genFailResult(e.getMessage());
        }
        // 保存登陆成功的用户信息至redis，每次登陆的时候查询redis是否此用户已经有一个客户端登陆了，如果登陆了，发送一个时间告知之前登陆的用户下线
        String userId = ShiroUtil.getUserId();

        Boolean flag = userService.ckeckAlreadyOnlineAndKickout(userId);
        if (flag){
            SocketIOClient socketIOClient = socketClientService.getSocketIOClientByUserId(userId);
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setMsgType(MsgType.推送通知);
            msgInfo.setContent("您已经在其它地方登录， 非本人操作请修改密码 ！！");
            socketIOClient.sendEvent(SocketConstant.KICK_OUT, msgInfo);
        }

        //登录成功返回ID和用户名以及通信密码
        return ResultGenerator.genSuccessResult(new LoginSuccessReturnDTO(ShiroUtil.getUserId(), ShiroUtil.getUserName(), ShiroUtil.getPwdConnect(), ShiroUtil.getTenantCode()));
    }

    @PostMapping("/logout")
    public Result logout() {
        //退出或超时失效时清除redis中的通信密码----在session监听器中已处理
        Subject subject = SecurityUtils.getSubject();
        if (null != subject && subject.isAuthenticated()) {
            // 修改用户为离线状态  socket中连接、断开做了处理
           //  ShiroUser shiroUser = (ShiroUser)SecurityUtils.getSubject().getSession().getAttribute(ChatConstant.SHIRO_USER_IN_SESSION);
           //  userService.changeStatusOffline(shiroUser.getUserId());
            subject.logout();
        }
        return ResultGenerator.genSuccessResult();
    }

    @PostMapping("/isOnline")
    public Result isOnline() {
        Subject subject = SecurityUtils.getSubject();
        if (null != subject && subject.isAuthenticated()) {
            return ResultGenerator.genSuccessResult();
        }
        return ResultGenerator.genUnauthorizedResult("登录失效或未登录");
    }


    @PostMapping("/adminKickOut")
    public Result adminKickOut(String userId) {
        Boolean flag = userService.ckeckAlreadyOnlineAndKickout(userId);
        if (flag){
            SocketIOClient socketIOClient = socketClientService.getSocketIOClientByUserId(userId);
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setMsgType(MsgType.推送通知);
            msgInfo.setContent("您已被管理员强制下线，请与管理员联系 ！！");
            socketIOClient.sendEvent(SocketConstant.ADMIN_KICK_OUT, msgInfo);
        }
        return ResultGenerator.genSuccessResult();
    }

}

